package top.kaoshanji.ch01;

import com.google.common.io.Resources;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;

/**
 * 代码清单 ch01-03：Optional示例(1.7节)
 * author kaoshanji
 * ^_^
 * create time 2024/12/5 11:09
 */
public class OptionalTest {

    private static final Logger logger = LogManager.getLogger(OptionalTest.class);

    static final String FILE_NAME = "gutenberg/alice30.txt";

    public static void main(String[] args) throws IOException {
        logger.info("...代码清单 ch01-03：Optional示例(1.7节)...");

        String fileContent = Resources.toString(Resources.getResource(FILE_NAME), StandardCharsets.UTF_8);
        List<String> wordList = List.of(fileContent.split("\\PL+"));

        // 获得Optional示例
        Optional<String> optionalValue = wordList.stream().filter(s -> s.contains("fred")).findFirst();
        System.out.println(optionalValue.orElse("No word") + " contains fred");

        logger.info("=========其不存在值的处理策略===========");
        Optional<String> optionalString = Optional.empty();

        // 设置默认值
        String result = optionalString.orElse("N/A");
        System.out.println("result: " + result);

        // 调用代码计算默认值
        result = optionalString.orElseGet(() -> Locale.getDefault().getDisplayName());
        System.out.println("result: " + result);

        // 抛出异常
        try {
            result = optionalString.orElseThrow(IllegalStateException::new);
            System.out.println("result: " + result);
        } catch (Throwable t) {
            t.printStackTrace();
        }


        logger.info("=========其存在值的情况下才消费该值===========");
        optionalValue = wordList.stream().filter(s -> s.contains("red")).findFirst();
        optionalValue.ifPresent(s -> System.out.println(s + " contains red"));

        var results = new HashSet<String>();
        optionalValue.ifPresent(results::add);

        logger.info("=========管道化Optional值===========");
        Optional<Boolean> added = optionalValue.map(results::add);
        System.out.println(added);

        System.out.println(inverse(4.0).flatMap(OptionalTest::squareRoot));
        System.out.println(inverse(-1.0).flatMap(OptionalTest::squareRoot));
        System.out.println(inverse(0.0).flatMap(OptionalTest::squareRoot));

        Optional<Double> result2 = Optional.of(-4.0).flatMap(OptionalTest::inverse).flatMap(OptionalTest::squareRoot);
        System.out.println(result2);

    }

    public static Optional<Double> inverse(Double x) {
        return x == 0 ? Optional.empty() : Optional.of(1 / x);
    }

    public static Optional<Double> squareRoot(Double x) {
        return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));
    }

}
